package net.da.data;
import org.hibernate.Session;

import java.util.Date;
import java.util.List;

import net.da.util.HibernateUtil;

public class EventManager {

    public static void main(String[] args) {
        EventManager mgr = new EventManager();

        if (args[0].equals("store")) {
            mgr.createAndStoreEvent("My Event", new Date());
        }
        else if (args[0].equals("list")) {
            List events = mgr.listEvents();
            for (int i = 0; i < events.size(); i++) {
                Event theEvent = (Event) events.get(i);
                System.out.println("Event: " + theEvent.getTitle() +
                                   " Time: " + theEvent.getDate());
            }
        }
        else if (args[0].equals("addpersontoevent")) {
            Long eventId1 = mgr.createAndStoreEvent("Event1", new Date());
            Long personId1 = mgr.createAndStorePerson("Dmitry", "Dzifuta");
            
            Long eventId2 = mgr.createAndStoreEvent("Event2", new Date());
            Long personId2 = mgr.createAndStorePerson("Alex", "Berezin");            
            
            
            mgr.addPersonToEvent(personId1, eventId1);
            mgr.addEventToPerson(personId2, eventId2);
            System.out.println("Added person " + personId1 + " to event " + eventId1);
            System.out.println("Added event " + eventId2 + " to person " + personId2);
        }
        HibernateUtil.getSessionFactory().close();
    }

    private Long createAndStoreEvent(String title, Date theDate) {
        Session session = HibernateUtil.getSessionFactory().getCurrentSession();
        session.beginTransaction();

        Event theEvent = new Event();
        theEvent.setTitle(title);
        theEvent.setDate(theDate);

        session.save(theEvent);
        session.getTransaction().commit();
        return theEvent.getId();
    }

    private Long createAndStorePerson (String firstName, String lastName) {
        Session session = HibernateUtil.getSessionFactory().getCurrentSession();
        session.beginTransaction();

        Person thePerson = new Person();
        thePerson.setFirstname(firstName);
        thePerson.setLastname(lastName);

        session.save(thePerson);
        session.getTransaction().commit();
        return thePerson.getId();
    }

    private List listEvents() {
        Session session = HibernateUtil.getSessionFactory().getCurrentSession();
        session.beginTransaction();
        List result = session.createQuery("from Event").list();
        session.getTransaction().commit();
        return result;
    }

    private void addPersonToEvent(Long personId, Long eventId) {

        Session session = HibernateUtil.getSessionFactory().getCurrentSession();
        session.beginTransaction();

        Person aPerson = (Person) session.load(Person.class, personId);
        Event anEvent = (Event) session.load(Event.class, eventId);

        aPerson.getEvents().add(anEvent);

        session.getTransaction().commit();
    }
    
    private void addEventToPerson(Long personId, Long eventId) {

        Session session = HibernateUtil.getSessionFactory().getCurrentSession();
        session.beginTransaction();

        Event anEvent = (Event) session
                .createQuery("select e from Event e left join fetch e.participants where e.id = :eid")
                .setParameter("eid", eventId)
                .uniqueResult(); // Eager fetch the collection so we can use it detached

        Person aPerson = (Person) session.load(Person.class, personId);

        session.getTransaction().commit();

        // End of first unit of work

        anEvent.getParticipants().add(aPerson);
        
//        aPerson.getEvents().add(anEvent); // aPerson (and its collection) is detached

        // Begin second unit of work

        Session session2 = HibernateUtil.getSessionFactory().getCurrentSession();
        session2.beginTransaction();

        session2.update(aPerson); // Reattachment of aPerson

        session2.getTransaction().commit();
    }    
    
}
